﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Afficheur
{
    /// <summary>
    /// Enumération qui décrit l'orientation du segment.
    /// Le segment peut prendre une orientation horizontale ou verticale
    /// </summary>
    public enum SegmentOrientation 
    { 
        horizontale,
        verticale
    }

    /// <summary>
    /// Enumération qui décrit les différentes couleurs que peut prendre le segment.
    /// La couleur du segment est obtenue à partir de l'affichage d'un fichier image 
    /// spécifique fabriqué pour le besoin. Le fichier image représente le segment dans 
    /// la couleur choisie. Changer la couleur du segment consiste à changer le fichier 
    /// image affiché. Les différents fichiers images sont stockés dans une 
    /// bibliothèque d'images : ImageList. 
    /// </summary>
    public enum SegmentColor
    {
        blue,
        green,
        red,
        yellow
    }
    
    /// <summary>
    /// Classe représentant un segment de l'afficheur
    /// </summary>
    public partial class Segment : UserControl
    {
        /// <summary>
        /// Attribut qui mémorise l'orientation Horizontale ou Verticale du segment
        /// </summary>
        private SegmentOrientation orientation;
        /// <summary>
        /// Attribut qui mémorise la couleur du segment
        /// </summary>
        private SegmentColor color;
        /// <summary>
        /// Attribut qui permet de régler l'allumage ou l'extinction du segment
        /// </summary>
        private Boolean on;

        /// <summary>
        /// Constructeur par défaut du segment
        /// </summary>
        public Segment()
        {
            InitializeComponent();

            // La bibliothèque d'images de référence est la imglSegmentH qui représente les segments dans 
            // leur orientation horizontale. On fabrique ici, à la volée, la bibliothèque verticale par 
            // rotation  à 90° de chacun des fichiers en orientation horizontale. 
            this.imglSegmentV.Images.Clear();
            this.imglSegmentV.ImageSize = new Size(this.imglSegmentH.ImageSize.Height, this.imglSegmentH.ImageSize.Width);
            foreach (Image image in this.imglSegmentH.Images)
            {
                Image imageClone = (Image)image.Clone();
                imageClone.RotateFlip(RotateFlipType.Rotate90FlipNone);
                this.imglSegmentV.Images.Add(imageClone);
            }

            // Mise en place de l'orientation horizontale, de la couleur et de l'éclairage
            this.pbSegment.SizeMode = PictureBoxSizeMode.StretchImage;
            this._Orientation = SegmentOrientation.verticale ;
            this._Color = SegmentColor.blue;
            this._On = true;
            this.Size = new Size(28, 122);
        }

        /// <summary>
        /// Définition d'une propriété permettant la gestion de la couleur du Segment
        /// Cette propriété s'appuie sur l'énumération SegmentColor et sur le numéro 
        /// de l'image dans l'imglSegmentH ou imglSegmentV
        /// </summary>
        public SegmentColor _Color
        {
            get { return color; }
            set 
            {
                // Y a t-il un changement ?...
                if (this.color != value)
                {
                    // ...Oui, alors on le mémorise
                    this.color = value;
                    // Mise à jour de la couleur
                    if (this._On) this.pbSegment.Image = this.getImage((int)value); //this.BackgroundImage = this.getImage((int)value);
                }
            }
        }

        /// <summary>
        /// Définition d'une propriété permettant la gestion de l'orientation du Segment
        /// Cette propriété s'appuie sur l'énumération SegmentOrientation et sur l'attribut 
        /// segmentOrientation
        /// </summary>
        public SegmentOrientation _Orientation
        {
            get { return orientation; }
            set
            {
                // Y a t-il un changement ?...
                if (this.orientation != value)
                {
                    // ...Oui, alors on le mémorise
                    this.orientation = value;
                    // ... en permutant largeur et hauteur
                    this.Size = new Size(this.Size.Height, this.Size.Width);

                    // ... et on bascule sur l'autre liste d'images
                    if (this._On) this.pbSegment.Image = this.getImage((int)this._Color); //this.BackgroundImage = this.getImage((int)this._Color);
                }
            }
        }

        /// <summary>
        /// Définition d'une propriété permettant la gestion de l'allumage du Segment
        /// Lorsque la propriété vaut True alors le segment est allumé
        /// Dans le cas contraire, le segment est éteint
        /// </summary>
        public Boolean _On
        {
            get { return this.on; }
            set 
            { 
                this.on = value;
                if (this.on)
                {
                    this.pbSegment.Image = this.getImage((int)this._Color);//this.BackgroundImage = this.getImage((int)this._Color);
                }
                else 
                {
                    this.pbSegment.Image = null;//this.BackgroundImage = null;
                }
            }
        }

        /// <summary>
        /// Fonction à usage interne qui retourne la bonne image selon l'orientation courante du segment
        /// </summary>
        /// <param name="imageIndex">L'indice représentant la couleur du segment</param>
        /// <returns></returns>
        private Image getImage(int imageIndex)
        {
            Image img;
            if (this._Orientation == SegmentOrientation.horizontale)
            {
                img = this.imglSegmentH.Images [ imageIndex ];
            }
            else
            {
                img = this.imglSegmentV.Images [ imageIndex ];
            }
            return img;
        }

        /// <summary>
        /// Procédure évènementielle utilisée ici afin d'empêcher 
        /// le redimensionnement du UserControl et son contenu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Segment_Resize(object sender, EventArgs e)
        {
            this.pbSegment.Size = this.Size;
        }

    }
}
